﻿using System;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;
using winS.UnityEditor.Undo;

namespace winS.UnityEditor.ProcessEditor
{
    internal class StepNodeSearchWindow : ScriptableObject, ISearchWindowProvider
    {
        public Type currentProcessType { get; set; }

        private StepGraphView stepGraphView;
        private ProcessEditor storyEditorWindow;

        private readonly NodeSearchGroup commonSearchGroup = new NodeSearchGroup("节点", 0);
        private readonly HashSet<Type> privateTypeHashSet = new HashSet<Type>();

        private readonly List<SearchTreeEntry> commonSearchTreeEntryList = new List<SearchTreeEntry>();
        private readonly Dictionary<Type, List<SearchTreeEntry>> searchTreeDictionary = new Dictionary<Type, List<SearchTreeEntry>>();

        public void Initialize(StepGraphView stepGraphView, ProcessEditor storyEditorWindow)
        {
            this.storyEditorWindow = storyEditorWindow;
            this.stepGraphView = stepGraphView;
        }

        public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
        {
            return searchTreeDictionary.TryGetValue(currentProcessType, out List<SearchTreeEntry> searchTreeEntryList) ? searchTreeEntryList : commonSearchTreeEntryList;
        }

        public void AddCommonEntry(string path, Type type)
        {
            commonSearchGroup.Add(null, path, type);
        }
        public void AddPrivateEntry(Type processType, string path, Type type)
        {
            privateTypeHashSet.Add(processType);
            commonSearchGroup.Add(processType, path, type);
        }
        /// <summary>
        /// 生成搜索树
        /// </summary>
        public void BuildSearchTree()
        {
            commonSearchGroup.GetSearchTreeEntryList(null, commonSearchTreeEntryList);

            foreach (var type in privateTypeHashSet)
            {
                List<SearchTreeEntry> privateSearchTreeList = new List<SearchTreeEntry>();
                commonSearchGroup.GetSearchTreeEntryList(type, privateSearchTreeList);
                searchTreeDictionary.Add(type, privateSearchTreeList);
            }
        }
        /// <summary>
        /// 选中节点-ISearchWindowProvider
        /// </summary>
        /// <param name="SearchTreeEntry"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context)
        {
            Vector2 editorWindowPosition = storyEditorWindow.position.position;
            Vector2 positionInEditorWindow = context.screenMousePosition - editorWindowPosition;
            Vector2 positionInContentView = stepGraphView.contentViewContainer.WorldToLocal(positionInEditorWindow);

            if (stepGraphView.waitConnectionOutputPort)
            {
                stepGraphView.stepNodeCreateState = StepNodeCreateState.CreateAndConnect;
                StepNode stepNode = stepGraphView.CreateStepAndNode(SearchTreeEntry.userData as Type, positionInContentView);
                Connectionline connectionline = stepNode.RequestConnect(stepGraphView.waitConnectionOutputPort);
                if (connectionline)
                {
                    CreateNodeCommand createNodeCommand = new CreateNodeCommand(stepNode, stepGraphView);
                    ConnectNodeCommand connectNodeCommand = new ConnectNodeCommand(connectionline, stepGraphView);
                    stepGraphView.processEditor.undoSystem.AddCommand(new GroupCommand("创建并连接节点", new List<IUndoCommand>() { connectNodeCommand, createNodeCommand }));
                }
                else stepGraphView.processEditor.undoSystem.AddCommand(new CreateNodeCommand(stepNode, stepGraphView));
                stepGraphView.stepNodeCreateState = StepNodeCreateState.None;
            }
            else stepGraphView.CreateStepAndNode(SearchTreeEntry.userData as Type, positionInContentView);
            return true;
        }
    }
}